package ThirdWeek;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Saturday {
    // 1419、数青蛙
    public int minNumberOfFrogs(String croakOfFrogs) {
        char[] s = croakOfFrogs.toCharArray();
        String t = "croak";
        int n = t.length();
        int[] hash = new int[n]; //模拟哈希表

        Map<Character,Integer> index = new HashMap<>(); //这个哈希表是为了记录croak中的每一个字符对应下标的位置
        for (int i = 0;i < n;i++) {
            index.put(t.charAt(i),i);
        }

        // 开始查询
        for (char ch : s) {
            //
            if (ch == t.charAt(0)) {
                // 要进行判断，哈希表中对应的k位置的值是否存在，如果存在就把k中的一个值移动到c为止，就是k--，c++
                if (hash[n - 1] != 0) {
                    // 如果存在
                    hash[n - 1]--;
                }
                // 不论是最后一个位置是否存在，我们的c这个位置都要进行+1操作
                hash[0]++;
            }else {
                // 如果不等，我们要判断是那个字符，之后取对应的下标，看对应下标的位置前一个是否存在，存在就--，取下标的++
                int i = index.get(ch);
                if (hash[i - 1] == 0) {
                    return -1;
                }
                hash[i - 1]--;
                hash[i]++;
            }
        }

        // 判断在遍历结束后，c-a之间呢是否是0，如果不是0就返回-1,
        for (int i = 0;i < n - 1;i++) {
            if (hash[i] != 0) {
                return -1;
            }
        }

        return hash[n - 1];
    }

    // 38、外观数列
    public String countAndSay(int n) {
        String ret = "1";
        for(int k = 1;k < n;k++) {
            // 遍历ret字符的次数，
            // 每次从0-ret.length()长度找连续重复的字符和其个数，赋值给ret
            StringBuilder tmp = new StringBuilder();
            for (int left = 0,right = 0; right < ret.length();) {
                int count = 0;
                while (right < ret.length() && ret.charAt(left) == ret.charAt(right)) {
                    right++;
                    count++;
                }
                tmp.append(count);
                tmp.append(ret.charAt(left));
                left = right;
            }
            ret = tmp.toString();
        }

        return ret;
    }

    // 6、Z字形变换
    public String convert(String s, int numRows) {
        // 模拟 + 找规律
        if (numRows == 1) {
            return s;
        }

        int d = numRows * 2 - 2; // 公差，每个数和下一个数相差多少个
        int n = s.length();
        StringBuilder ret = new StringBuilder();

        // 处理第一行
        for (int i = 0;i < n;i += d) {
            ret.append(s.charAt(i));
        }

        // 处理中间层
        for (int k = 1; k < numRows - 1;k++) {
            for (int i = k,j = d - k;i < n || j < n;i += d,j += d) {
                if(i < n) {
                    ret.append(s.charAt(i));
                }
                if(j < n) {
                    ret.append(s.charAt(j));
                }
            }
        }

        // 处理最后一行
        for (int i = numRows - 1;i < n;i += d) {
            ret.append(s.charAt(i));
        }
        return ret.toString();
    }

    public String convert1(String s, int numRows) {
        if(numRows < 2) {
            return s;
        }
        List<StringBuilder> row = new ArrayList<>();
        for(int i = 0; i < numRows;i++) {
            //代表有多少行
            row.add(new StringBuilder());
        }
        char[] ss = s.toCharArray();
        int i = 0,flag = -1;
        for(char ch : ss) {
            row.get(i).append(ch);
            if(i == 0 || i == numRows - 1) {
                //说明到达字符交换的条件了
                //i==0的时候把flag变为整数去加，i == numRows - 1的时候就把flag再赋值为负的进行从大往小的去减少
                flag = -flag;
            }
            i += flag;
        }
        StringBuilder ret = new StringBuilder();
        for(StringBuilder rows : row) {
            ret.append(rows);
        }
        return ret.toString();
    }


    // 495、提莫攻击
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int ret = 0;
        for (int i = 1;i < timeSeries.length;i++) {
            int x = timeSeries[i] - timeSeries[i - 1];
            if (x >= duration) {
                ret += duration;
            }else {
                ret += x;
            }
        }
        // 最后一次攻击之后没有进行计数时间，所以我们要那最后一次攻击计上
        return ret + duration;
    }
}
